﻿/*
 * Copyright © 2020, Wuxi Safover Intelligent Technology Co., Ltd. All rights reserved.
 * 
 * 无锡安永智能科技有限公司版权所有，未经许可，不得用于商业用途
 * 
 * Visit: https://www.safover.com/ 
 */

using System;
using System.Threading;
using static Safover.LidarCollector.Managers.DeviceManager;
using Safover.Lidar.DataContract;

namespace Safover.LidarCollector.Managers
{
    internal class HorizontalScan : SingleScan
    {
        protected override string Name => "HorizontalScan";

        protected override LidarWorkMode LidarWorkMode => LidarWorkMode.Horizontal;

        protected override LidarScanMode LidarScanMode => LidarScanMode.Horizontal;

        internal HorizontalScan(PeriodicScanParams periodicScanParams) : base(periodicScanParams)
        { }

        internal SingleScanResult Scan(//Stopwatch stopwatch, TimeSpan? timeAllowed, 
            HorizontalScanControlLogic scanContolLogic, 
            //string folderName, 
            DataCacher cacher, SingleCollectionWorkingStatusChangedEventHandler handler)
        {
            Log.DebugWriteLine($"{Name}: Ready to start {LidarWorkMode} Scan.");

            HScanInstruction instruction = scanContolLogic.Tick();

            if (!instruction.CanScan) return SingleScanResult.PeriodicalScanFinished;

            var horizontalAngle = (float)instruction.ScanAngle;
            var verticalAngle = instruction.FixedVerticalAngle; 

            handler?.Invoke(new SingleCollectionWorkingStatusChangedEventArgs
            {
                IsSingleCollecting = true,
                SingleLidarWorkMode = LidarWorkMode,
                PercentageCompletion = .05f,
                Message = $"Moving Rotary Table to HAngle={horizontalAngle}",
                CountDownSecondsForNextFixedCollection = 0
            });

            if (MoveRotaryTableHorizontally(horizontalAngle))
            {
                Log.DebugWriteLine($"----- {Name}: Rotary Table is Ready for {LidarWorkMode} step scan, fixed vertical angle = 【{verticalAngle}】, horizontial angle = 【{horizontalAngle}】.");
            }

            handler?.Invoke(new SingleCollectionWorkingStatusChangedEventArgs
            {
                IsSingleCollecting = true,
                SingleLidarWorkMode = LidarWorkMode,
                PercentageCompletion = .15f,
                Message = "Rotary Table is Ready",
            });

            if (!DeviceFactoryInstance.OpticalMaserDevice.StartLasar())
            {
                throw new OpticalMaserMalfunctionException($"{Name}: Failed to start optical maser.");
            }

            Log.DebugWriteLine($"{Name}: Lasar is on.");

            handler?.Invoke(new SingleCollectionWorkingStatusChangedEventArgs
            {
                IsSingleCollecting = true,
                SingleLidarWorkMode = LidarWorkMode,
                Message = "Laser is on",
                PercentageCompletion = .25f
            });

            StartCatchingData(cacher, TimeSpan.FromSeconds(SingleAcquisitionTimeout));

            handler?.Invoke(new SingleCollectionWorkingStatusChangedEventArgs
            {
                IsSingleCollecting = false,
                SingleLidarWorkMode = LidarWorkMode,
                PercentageCompletion = .95f,
                Message = "Laser is off, Saving Data",
            });

            var startAngle = scanContolLogic.StartAngle;
            var endAngle = scanContolLogic.EndAngle;

            FinishSingleScan(cacher, startAngle: 0, endAngle: 0, horizontalAngle: horizontalAngle, vertialAngle: verticalAngle);

            if (!DeviceFactoryInstance.OpticalMaserDevice.StopLasar())
            {
                throw new OpticalMaserMalfunctionException("Failed to stop optical maser.");
            }

            handler?.Invoke(new SingleCollectionWorkingStatusChangedEventArgs
            {
                IsSingleCollecting = false,
                SingleLidarWorkMode = LidarWorkMode,
                PercentageCompletion = 1f,
            });

            Log.DebugWriteLine($"[Thread={Thread.CurrentThread.Name}]: {LidarWorkMode}, single collection done.");

            //if (stopwatch != null && stopwatch.Elapsed >= timeAllowed)
            //{
            //    Log.DebugWriteLine($"[MultiScan.{lidarWorkMode}]: TotalScan duration finished.");
            //    return SingleScanResult.MultiModeTimeout;
            //}

            return SingleScanResult.Success;
        }

    }
}
